/*
 * UAE - The Un*x Amiga Emulator
 *
 * Drive Click emulation stuff
 *
 * Copyright 2004 James Bagg, Toni Wilen
 */

#pragma once

#ifdef DRIVESOUND

namespace Floppy
{
    class Sound
    {
        private:

            static const int CLICK_TRACKS = 84;

            static const int DS_CLICK = 0;
            static const int DS_SPIN = 1;
            static const int DS_SPINND = 2;
            static const int DS_START = 3;
            static const int DS_SNATCH = 4;
            static const int DS_END = 5;

            static const int DS_SHIFT = 10;

            class FloppySample
            {
                public:

                    int len;
                    int pos;
                    short* p;
                    int indexes[CLICK_TRACKS];
                    int lengths[CLICK_TRACKS];
                    int freq;

                    FloppySample ()
                    {
                        p = nullptr;
                        Clear();
                    }

                    ~FloppySample ()
                    {
                        Clear();
                    }

                    void Clear()
                    {
                        Helpers::safe_delete(&p);

                        freq = 44100;
                        len = 0;
                        pos = 0;
                        Helpers::zeroes(&indexes);
                        Helpers::zeroes(&lengths);
                    }

                    int GetStep();
                    void ProcessClicks();
                    int LoadSample(byte* buf);
                    void DecodeWav(byte* s);
            };

            class FloppySamples
            {
                public:

                    FloppySample Samples[DS_END];
                    int drv_starting;
                    int drv_spinning;
                    int drv_has_spun;
                    int drv_has_disk;
                    bool wave_initialized;
                    int prevcyl;

                    FloppySamples ()
                    {
                        drv_starting = false;
                        drv_spinning = false;
                        drv_has_spun = false;
                        drv_has_disk = false;
                        prevcyl = 0;
                        wave_initialized = false;
                    }

                    void Clear()
                    {
                        drv_starting = false;
                        drv_spinning = false;
                        drv_has_spun = false;
                        drv_has_disk = false;
                        wave_initialized = false;
                        prevcyl = 0;

                        for (int i = 0; i < DS_END; i++)
                            Samples[i].Clear();
                    }
            };

            static FloppySamples Floppies[4];
            static short* clickbuffer;
            static int clickcnt;

            static short getsample();
            static short limit(int v);
            static void mix();

        public:

            static CArray<CString>floppy_sounds_names;

            static void Clear();
            static void Init();
            static void click(int drive, int startOffset);
            static void motor(int drive, int running);
            static void insert(int drive, bool eject);
            static void mix(short* sndbuffer, int size);
            static void check_prefs();
            static void load_floppy_sounds_names();
    };
}

#endif